package com.example.alibabavodossservice.vod.uploadMore;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.PutObjectResult;
import com.aliyun.oss.model.UploadFileRequest;
import com.aliyuncs.vod.model.v20170321.*;

import java.io.File;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLEncoder;

import static com.example.alibabavodossservice.vod.InitVODConstants.*;


public class Cmd {

    /**
     * URL批量拉取上传
     * URL编码，多个地址之间以半角逗号（,）分隔，最多支持20个
     * 允许用户提供一个包含视频文件URL的文本文件，通过指定该文本文件的URL，阿里云VOD会自动解析其中的URL信息，
     * 并将这些视频文件批量上传到阿里云VOD平台进行存储，并为用户生成对应的视频ID
     *
     * @param urls url数组
     * @return UploadMediaByURLResponse URL批量拉取上传响应数据
     * @throws Exception 异常
     */
    public static UploadMediaByURLResponse uploadMediaByURL(String[] urls) throws Exception {
        UploadMediaByURLRequest request = new UploadMediaByURLRequest();
        //解析urls
        String encodeUrl = encodeUrlWithUTF8(urls);
        //视频源文件URL
        request.setUploadURLs(encodeUrl);
        //上传视频元数据信息
        JSONObject uploadMetadata = new JSONObject();
        //需要上传的视频源文件URL，与UploadURLs里的URL匹配才能生效
        uploadMetadata.put("SourceUrl", encodeUrl);
        //视频标题
        uploadMetadata.put("Title", "upload by url sample");
        JSONArray uploadMetadataList = new JSONArray();
        uploadMetadataList.add(uploadMetadata);
        request.setUploadMetadatas(uploadMetadataList.toJSONString());
        return VOD_CLIENT.getAcsResponse(request);
    }

    /**
     * 获取URL上传信息
     * 通过URL上传时返回的JobId或者上传时使用的URL来获取URL上传信息，包括URL上传状态、UserData、创建时间、完成时间等。
     *
     * @return GetURLUploadInfosResponse 获取URL上传信息响应数据
     * @throws Exception
     */
    public static GetURLUploadInfosResponse getURLUploadInfos(String[] urls, String[] jobs) throws Exception {
        GetURLUploadInfosRequest request = new GetURLUploadInfosRequest();
        request.setUploadURLs(encodeUrlWithUTF8(urls));
        //TODO:JobId列表，可以通过GetPlayInfo接口中返回的PlayInfo结构体中获取
        request.setJobIds("exampleID1,exampleID2");
        return VOD_CLIENT.getAcsResponse(request);
    }


    /**
     * 转换URL编码返回逗号分割的url字符串
     *
     * @param urls urls数组
     * @return 逗号分割的url字符串
     * @throws UnsupportedEncodingException
     */
    public static String encodeUrlWithUTF8(String[] urls) throws UnsupportedEncodingException {
        StringBuffer urtBuilder = new StringBuffer();
        for (String url : urls) {
            String encodeUrl = URLEncoder.encode(url, "UTF-8");
            urtBuilder.append(encodeUrl).append(",");
        }
        return urtBuilder.toString();
    }


    /**
     * 文件上传
     *
     * @param ossClient     ossClient
     * @param uploadAddress uploadAddress
     * @param file          ioFIle
     */
    public static PutObjectResult uploadLocalFile(OSSClient ossClient, JSONObject uploadAddress, File file) {
        PutObjectResult putObjectResult = null;
        extractUploadAddress(uploadAddress);
        try {
            putObjectResult = ossClient.putObject(BUCKET_NAME, OBJECT_NAME, file);
        } catch (Exception exception) {
            System.out.println("Failed to upload local file. " + exception.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
        return putObjectResult;
    }

    /**
     * 网络流式上传(url直链上传)
     *
     * @param ossClient     ossClient
     * @param uploadAddress 上传地址
     * @param url           url直链
     */
    public static void uploadURLFile(OSSClient ossClient, JSONObject uploadAddress, String url) {
        extractUploadAddress(uploadAddress);
        try {
            InputStream inputStream = new URL(url).openStream();
            PutObjectResult result = ossClient.putObject(BUCKET_NAME, OBJECT_NAME, inputStream);
            // 如果上传成功，则返回200。
            System.out.println(result.getResponse().getStatusCode());
        } catch (Exception e) {
        } finally {
            // 关闭OSSClient。
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

    /**
     * 断点续传上传
     *
     * @param ossClient     ossClient
     * @param uploadAddress 上传地址
     */
    public static void uploadEnableCheckPointFile(OSSClient ossClient, JSONObject uploadAddress,File file) {
        extractUploadAddress(uploadAddress);
        try {
            // 通过UploadFileRequest设置单个参数。
            UploadFileRequest uploadFileRequest = new UploadFileRequest(BUCKET_NAME, OBJECT_NAME);
            // 指定上传的文件
            uploadFileRequest.setUploadFile(file.toString());
            // 指定上传并发线程数，默认值为1。
            uploadFileRequest.setTaskNum(20);
            // 指定上传的分片大小，单位为字节。
            uploadFileRequest.setPartSize(SLICE_SIZE);
            // 开启断点续传，默认关闭。
            uploadFileRequest.setEnableCheckpoint(true);
            // 记录本地分片上传结果的文件。上传过程中的进度信息会保存在该文件中，如果某一分片上传失败，再次上传时会根据文件中记录的点继续上传。上传完成后，该文件会被删除。
            // 如果未设置该值，默认与待上传的本地文件同路径，名称为${uploadFile}.ucp。
            uploadFileRequest.setCheckpointFile(file.toString());
            ossClient.uploadFile(uploadFileRequest);
        } catch (Throwable e) {
            System.out.println("Failed to upload file, localFile: " + file + " with error: " + e.getMessage());
        } finally {
            // 关闭OSSClient。
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }


}
